<?php
/**
 * crcl/base
 *
 * Copyright 2013 CRCL - André Sabosch - info@crcl.de
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace crcl\base\file;

class Csv implements \Iterator
{
  const ROW_SIZE = 4096;

  /**
   * This is the constructor.It try to open the csv file.The method throws an exception
   * on failure.
   *
   * @access public
   *
   * @param string $sFile      The csv file.
   * @param string $cDelimiter The delimiter.
   *
   * @throws Exception
   */
  public function __construct($sFile, $cDelimiter = ';')
  {
    if (!\file_exists($sFile))
    {
      throw new Exception('File not readable.', Exception::ERROR_CSV_NOTREADABLE,
          array('file' => $sFile, 'delimiter' => $cDelimiter));
    }
    else
    {
      $this->hFile = \fopen($sFile, 'r');
      $this->cDelimiter = $cDelimiter;
    }
  }

  /**
   * This method resets the file pointer.
   *
   * @access public
   */
  public function rewind()
  {
    $this->iRowCounter = 0;
    rewind($this->hFile);
  }

  /**
   * This method returns the current csv row as a 2 dimensional array
   *
   * @access public
   * @return array The current csv row as a 2 dimensional array
   */
  public function current()
  {
    $this->aCurrentLine = \fgetcsv($this->hFile, self::ROW_SIZE, $this->cDelimiter);
    $this->iRowCounter++;

    return $this->aCurrentLine;
  }

  /**
   * This method returns the current row number.
   *
   * @access public
   * @return int The current row number
   */
  public function key()
  {
    return $this->iRowCounter;
  }

  /**
   * This method checks if the end of file is reached.
   *
   * @access public
   * @return boolean Returns true on EOF reached, false otherwise.
   */
  public function next()
  {
    return !\feof($this->hFile);
  }

  /**
   * This method checks if the next row is a valid row.
   *
   * @access public
   * @return boolean If the next row is a valid row.
   */
  public function valid()
  {
    if (!$this->next())
    {
      \fclose($this->hFile);

      return \FALSE;
    }

    return \TRUE;
  }

  /** PRIVAT **************************************************************************************/

  /**
   * The pointer to the cvs file.
   * @var resource
   * @access private
   */
  private $hFile = \NULL;

  /**
   * The current element, which will
   * be returned on each iteration.
   * @var array
   * @access private
   */
  private $aCurrentLine = \NULL;

  /**
   * The row counter.
   * @var int
   * @access private
   */
  private $iRowCounter = \NULL;

  /**
   * The delimiter for the csv file.
   * @var str
   * @access private
   */
  private $cDelimiter = \NULL;
}